#include "serthread.h"
#include <QDebug>
#include <QThread>
#include <QTextCodec>


SerThread::SerThread(QObject* parent)
    : QObject { parent }
    , timer(new QTimer(this))
    , buffer(0)

{
    // 动态分配空间，指定父对象
    MySerial = new QSerialPort(this);

    QObject::connect(MySerial, &QSerialPort::readyRead, this, &SerThread::RecvData);
}
SerThread::~SerThread()
{
    delete info;
}

void SerThread::SendData(QByteArray data, bool flag)
{
    if(data.isEmpty())
        return;
    if(flag == true) // 十六进制发送标志
    {
        //hex直接发送
        MySerial->write(data);

    }
    else{
        //判断编码格式再发送
        data = QTextCodec::codecForName("UTF-8")->fromUnicode(data);
        MySerial->write(data);
    }
}

void SerThread::RecvData()
{
    // 将数据读入缓冲区
    buffer.append(MySerial->readAll());
    QByteArray data = buffer;
    buffer.clear();
    if (data.isEmpty()) {
        return;
    }
    emit sig_isRecvData(data);
    qDebug() << "Rcv data:" << data;
}

void SerThread::SerialClose()
{
    qDebug() << "SerialClose" << QThread::currentThread();
    if (MySerial->isOpen()) // 如果串口已经打开了 先给他关闭了
    {
        MySerial->clear();
        MySerial->close();
    }
}

void SerThread::do_CloseSerial()
{
    SerialClose();
}

void SerThread::do_OpenSerial()
{
    qDebug() << "SerialOpen" << QThread::currentThread();
    this->SerialClose();
    MySerial->setPortName(QString(info->comName));
    // 尝试用读写模式打开串口
    if (!MySerial->open(QIODevice::ReadWrite)) {
        // 发送串口打开失败
        emit sig_noSerialOpen();
        qDebug() << QString(info->comName) << "open failed";
        return;
    }
    InfoSet.clear();
    InfoSet.append("串口:");
    InfoSet.append(QString(info->comName));
    qDebug() << InfoSet << "Succed";
    // 检查波特率合法
    bool Bflag = MySerial->setBaudRate(qint32(info->baudRate));
    if (Bflag) {
        InfoSet.append("baud:");
        QString baudRateinfo = QString::number(int(info->baudRate), 10);
        InfoSet.append(baudRateinfo);
    } else {
        InfoSet.append("baud: Unknow");
    }
    // 设置数据位
    switch (info->dataBits) {
    case 0:
        MySerial->setDataBits(QSerialPort::Data5);
        //                qDebug() <<"dataBitsSet:Data5";
        InfoSet.append(tr(" 数据位:5"));
        break;
    case 1:
        MySerial->setDataBits(QSerialPort::Data6);
        //                qDebug() <<"dataBitsSet:Data6";
        InfoSet.append(tr(" 数据位:6"));
        break;
    case 2:
        MySerial->setDataBits(QSerialPort::Data7);
        //                qDebug() <<"dataBitsSet:Data7";
        InfoSet.append(tr(" 数据位:7"));
        break;
    case 3:
        MySerial->setDataBits(QSerialPort::Data8);
        //                qDebug() <<"dataBitsSet:Data8";
        InfoSet.append(tr(" 数据位:8"));
        break;
    default:
        MySerial->setDataBits(QSerialPort::UnknownDataBits);
        //                qDebug() <<"dataBitsSet:UnknownDataBits";
        InfoSet.append(tr(" 数据位:Unknown"));
        break;
    }
    // 设置校验位
    switch (info->parity) {
    case 0:
        MySerial->setParity(QSerialPort::EvenParity);
        //                qDebug() <<"paritySet:EvenParity";
        InfoSet.append(tr(" 校验位:Even"));
        break;
    case 1:
        MySerial->setParity(QSerialPort::MarkParity);
        //                qDebug() <<"paritySet:MarkParity";
        InfoSet.append(tr(" 校验位:Mark"));
        break;
    case 2:
        MySerial->setParity(QSerialPort::NoParity);
        //                qDebug() <<"paritySet:NoParity";
        InfoSet.append(tr(" 校验位:None"));
        break;
    case 3:
        MySerial->setParity(QSerialPort::OddParity);
        //                qDebug() <<"paritySet:OddParity";
        InfoSet.append(tr(" 校验位:Odd"));
        break;
    case 4:
        MySerial->setParity(QSerialPort::SpaceParity);
        //                qDebug() <<"paritySet:SpaceParity";
        InfoSet.append(tr(" 校验位:Space"));
        break;
    default:
        MySerial->setParity(QSerialPort::UnknownParity);
        //                qDebug() <<"paritySet:UnknownParity";
        InfoSet.append(tr(" 校验位:Unknown"));
        break;
    }
    // 设置停止位
    switch (info->stopBits) {
    case 0:
        MySerial->setStopBits(QSerialPort::OneStop);
        //                qDebug() <<"stopBitsSet:1";
        InfoSet.append(tr(" 停止位:1"));
        break;
    case 1:
        MySerial->setStopBits(QSerialPort::OneAndHalfStop);
        //                qDebug() <<"stopBitsSet:1.5";
        InfoSet.append(tr(" 停止位:1.5"));
        break;
    case 2:
        MySerial->setStopBits(QSerialPort::TwoStop);
        //                qDebug() <<"stopBitsSet:2";
        InfoSet.append(tr(" 停止位:2"));
        break;
    default:
        MySerial->setStopBits(QSerialPort::UnknownStopBits);
        //                qDebug() <<"stopBitsSet:UnknownParity";
        InfoSet.append(tr(" 停止位:Unknown"));
        break;
    }
    emit sig_SetInfo(InfoSet);
    qDebug() << "InfoSet" << InfoSet;
}

void SerThread::do_RecvSerialConfig(Sinfo* data)
{
    if (info != nullptr) // 删除原先内存空间
    {
        delete info;
    }
    this->info = new Sinfo; // 防止内存泄漏,关闭窗口时 delete info;
    // 接收参数设置
    this->info->Encode = data->Encode;
    this->info->baudRate = data->baudRate;
    this->info->comName = data->comName;
    this->info->dataBits = data->dataBits;
    this->info->flowControl = data->flowControl;
    this->info->parity = data->parity;
    this->info->stopBits = data->stopBits;
}
